// <copyright file="Dialog.cs" company="YUIAsp.Net">
// Copyright (c) 2009 All Right Reserved
// </copyright>
// <author>raul popescu</author>
// <email>dev@yuiasp.net</email>
// <date>2009-01-30</date>
// <summary>YUIAsp.Net File</summary>

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using YUIAspNet.Common;

#region Embedded resources definitions
[assembly: WebResource("YUIAspNet.Dialog.Dialog.js", "text/javascript")]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.Dialog.container-core.css", "text/css", PerformSubstitution = true)]
[assembly: WebResource("YUIAspNet.EmbeddedSkins.DefaultSkin.Dialog.container-skin.css", "text/css", PerformSubstitution = true)]
#endregion

namespace YUIAspNet
{
    /// <summary>
    /// Dialog control.
    /// </summary>
    [ToolboxItem(true)]
    [ParseChildren(true)]
    public class Dialog : YUIScriptBaseControl, INamingContainer
    {
        Panel _pnlBodyContent;
        Panel _pnlHeaderContent;
        Panel _pnlFooterContent;
        private IList<DialogButton> _dialogButtonList;

        /// <summary>
        /// Initializes a new instance of the <see cref="SimpleDialog"/> class.
        /// </summary>
        public Dialog()
        {
            _pnlBodyContent = new Panel();
            _pnlHeaderContent = new Panel();
            _pnlFooterContent = new Panel();

            ControlKey = "Dialog";//we use the same references for all types of charts
            Closeable = true;
            Centered = true;
        }

        /// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            this.Style.Add("display", "none");

            _pnlBodyContent.ID = "bodyContent";
            Controls.Add(_pnlBodyContent);

            _pnlHeaderContent.ID = "headerContent";
            Controls.Add(_pnlHeaderContent);

            _pnlHeaderContent.ID = "footerContent";
            Controls.Add(_pnlFooterContent);

            if (this.TextTemplate != null)
                TextTemplate.InstantiateIn(_pnlBodyContent);

            if (this.HeaderTemplate != null)
                HeaderTemplate.InstantiateIn(_pnlHeaderContent);

            if (this.FooterTemplate != null)
                FooterTemplate.InstantiateIn(_pnlFooterContent);
        }

        /// <summary>
        /// Registers the style sheets for the current control.
        /// Must be overriden in the parent control to add any css file reference.
        /// </summary>
        protected override void RegisterStyleSheets()
        {
            RegisterEmbeddedStylesheet("Dialog", "container-core.css");
            RegisterEmbeddedStylesheet("Dialog", "container-skin.css");
            RegisterEmbeddedStylesheet("Button", "button.css");
        }

        /// <summary>
        /// Register the values to send to the client control for initialization.
        /// </summary>
        protected override void RegisterClientInitialization()
        {
            AddProperty("ThemeName", CurrentTheme2CssClass());
            AddProperty("Visible", Visible);
            AddProperty("Centered", Centered);
            AddProperty("Draggable", Draggable);
            AddProperty("Closeable", Closeable);
            AddProperty("BodyContentID", _pnlBodyContent.ClientID);
            AddProperty("HeaderContentID", _pnlHeaderContent.ClientID);
            AddProperty("ConstrainToViewport", ConstrainToViewport);
            AddProperty("Icon", new StringBuilder(GetIconName(Icon)), true);
            AddProperty("Modal", Modal);
            AddProperty("Effect", Effect);
            AddProperty("DialogButtonList", Serialize(DialogButtonList), true);
            AddProperty("Underlay", Underlay.ToString().ToLowerInvariant());
            if(ContentURL != null)
                AddProperty("ContentURL", ContentURL);
        }

        private static string GetIconName(DialogIcon icon)
        {
            switch (icon)
            {
                case DialogIcon.Alarm:
                    return "YAHOO.widget.SimpleDialog.ICON_ALARM";
                case DialogIcon.Block:
                    return "YAHOO.widget.SimpleDialog.ICON_BLOCK";
                case DialogIcon.Help:
                    return "YAHOO.widget.SimpleDialog.ICON_HELP";
                case DialogIcon.Info:
                    return "YAHOO.widget.SimpleDialog.ICON_INFO";
                case DialogIcon.Tip:
                    return "YAHOO.widget.SimpleDialog.ICON_TIP";
                case DialogIcon.Warning:
                    return "YAHOO.widget.SimpleDialog.ICON_WARN";

                default: return ""; // no default icon
            }
        }

        private static StringBuilder Serialize(ICollection<DialogButton> dialogButtonList)
        {
            StringBuilder sb = new StringBuilder("[");

            if (dialogButtonList != null && dialogButtonList.Count > 0)
            {
                foreach (var btn in dialogButtonList)
                {
                    sb.AppendFormat(CultureInfo.InvariantCulture, "{0}{{text: '{1}', handler: {2}", sb.Length > 1 ? "," : "", btn.Text, btn.Handler);

                    if (btn.IsDefault)
                        sb.Append(", isDefault: true");

                    sb.Append("}");
                }
            }

            sb.Append("]");

            return sb;
        }

        /// <summary>
        /// Registers any additional scripts to include for this control.
        /// </summary>
        protected override void RegisterScriptReferences()
        {
            AddScriptReference(new ScriptReference("YUIAspNet.Dialog.Dialog.js", this.GetType().Assembly.FullName));
        }

        #region Public Properties

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="SimpleDialog"/> is centered.
        /// </summary>
        /// <value><c>true</c> if centered; otherwise, <c>false</c>.</value>
        public bool Centered { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="SimpleDialog"/> is draggable.
        /// </summary>
        /// <value><c>true</c> if draggable; otherwise, <c>false</c>.</value>
        public bool Draggable { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="SimpleDialog"/> is closeable.
        /// </summary>
        /// <value><c>true</c> if closeable; otherwise, <c>false</c>.</value>
        public bool Closeable { get; set; }

        /// <summary>
        /// Gets or sets the content URL.
        /// </summary>
        /// <value>The content URL.</value>
        public Uri ContentURL { get; set; }

        /// <summary>
        /// Gets or sets the text of the dialog.
        /// </summary>
        /// <value>The text.</value>
        public string Text
        {
            get
            {
                if (_pnlBodyContent.Controls.Count > 0 && _pnlBodyContent.Controls[0] is LiteralControl)
                    return ((LiteralControl) _pnlBodyContent.Controls[0]).Text;

                return null;
            }
            set
            {
                _pnlBodyContent.Controls.Clear();
                _pnlBodyContent.Controls.Add(new LiteralControl(value));
            }
        }

        /// <summary>
        /// Gets or sets the text template.
        /// </summary>
        /// <value>The text template.</value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate TextTemplate { get; set; }

        /// <summary>
        /// Gets or sets the header text of the dialog.
        /// </summary>
        /// <value>The text.</value>
        public string Header
        {
            get
            {
                if (_pnlHeaderContent.Controls.Count > 0 && _pnlHeaderContent.Controls[0] is LiteralControl)
                    return ((LiteralControl) _pnlHeaderContent.Controls[0]).Text;

                return null;
            }
            set
            {
                _pnlHeaderContent.Controls.Clear();
                _pnlHeaderContent.Controls.Add(new LiteralControl(value));
            }
        }

        /// <summary>
        /// Gets or sets the header text of the dialog.
        /// </summary>
        /// <value>The text.</value>
        public string Footer
        {
            get
            {
                if (_pnlFooterContent.Controls.Count > 0 && _pnlFooterContent.Controls[0] is LiteralControl)
                    return ((LiteralControl) _pnlFooterContent.Controls[0]).Text;

                return null;
            }
            set
            {
                _pnlFooterContent.Controls.Clear();
                _pnlFooterContent.Controls.Add(new LiteralControl(value));
            }
        }

        /// <summary>
        /// Gets or sets the header template.
        /// </summary>
        /// <value>The header template.</value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate HeaderTemplate { get; set; }

        /// <summary>
        /// Gets or sets the footer template.
        /// </summary>
        /// <value>The footer template.</value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate FooterTemplate { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether to constrain to viewport.
        /// </summary>
        public bool ConstrainToViewport { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="SimpleDialog"/> is modal.
        /// </summary>
        /// <value><c>true</c> if modal; otherwise, <c>false</c>.</value>
        public bool Modal { get; set; }

        /// <summary>
        /// Gets or sets the effect.
        /// </summary>
        /// <value>The effect.</value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ContainerEffect Effect {get; set; }

        /// <summary>
        /// Gets or sets the dialog button list.
        /// </summary>
        /// <value>The dialog button list.</value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public IList<DialogButton> DialogButtonList 
        { 
            get
            {
                if(_dialogButtonList == null)
                    _dialogButtonList = new List<DialogButton>();

                return _dialogButtonList;
            }
        }

        /// <summary>
        /// Gets or sets a value that indicates whether the dialog is visible when the page loads.
        /// </summary>
        public new bool Visible { get; set; }

        /// <summary>
        /// Gets or sets the icon of the dialog.
        /// </summary>
        /// <value>The icon.</value>
        public DialogIcon Icon { get; set; }

        /// <summary>
        /// Gets or sets the underlay.
        /// </summary>
        /// <value>The underlay.</value>
        public Underlay Underlay { get; set; }

        /// <summary>
        /// Gets or sets the client handler before show.
        /// </summary>
        public string OnClientBeforeShow { get; set; }

        /// <summary>
        /// Gets or sets the client handler after show.
        /// </summary>
        public string OnClientAfterShow { get; set; }

        #endregion
    }
}
